package com.sofwin.aspectj;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sofwin.Constants;
import com.sofwin.mapper.SysUserMapper;
import com.sofwin.pojo.OperatorLog;
import com.sofwin.pojo.SysUser;
import com.sofwin.util.DateUtil;
import com.sofwin.zj.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

/**
 * @packageName: com.sofwin.aspectj
 * @user: andyliu
 * @date: 2023/1/4 17:06
 * @email 115176513@qq.com
 * @description: 123123
 */
@Component
@Aspect
public class LogAop {

    @Autowired
    private SysUserMapper mapper;
    // 环绕增强可以获取到输入参数和输出结果
    // 1
    // 2
    // 3 567
    // 3 456
    // 4
    @Around("@annotation(com.sofwin.zj.Log)")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object result = point.proceed();
        operaterLog(point,0,result);
        return result;
    }

    // 异常增强
    @AfterThrowing(value = "@annotation(com.sofwin.zj.Log)",throwing = "ex")
    public void afterThrowing(JoinPoint point,Exception ex) throws JsonProcessingException, NoSuchMethodException {
        operaterLog(point,1,ex);
    }

    public void operaterLog(JoinPoint point,int flag,Object exception) throws JsonProcessingException, NoSuchMethodException {
        System.out.println(".......................");
        // 模块信息
        Object target = point.getTarget();
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        Method currentMethod = target.getClass().getDeclaredMethod(signature.getName(),methodSignature.getParameterTypes());
        Log declaredAnnotation = currentMethod.getDeclaredAnnotation(Log.class);
        String module = declaredAnnotation.module();
        // 当前用户
        // 在普通的java类中获取servlet的相关信息
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpSession session = request.getSession();
        SysUser user = (SysUser) session.getAttribute(Constants.CURRENT_USER);
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        Map parameterMap = request.getParameterMap();
        // map转为json格式
        ObjectMapper objectMapper = new ObjectMapper();
        // 请求参数的json字符串
        String parameters = objectMapper.writeValueAsString(parameterMap);
        String results ="";
        results = objectMapper.writeValueAsString(exception);
        String ip = request.getRemoteAddr();
        OperatorLog operatorLog = new OperatorLog();
        operatorLog.setUserId(user.getId());
        operatorLog.setOperatorDate(DateUtil.getDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
        operatorLog.setFlag(flag);
        operatorLog.setModule(module);
        operatorLog.setIp(ip);
        operatorLog.setUrl(requestURI);
        operatorLog.setMethod(method);
        operatorLog.setParams(parameters);
        operatorLog.setResult(results);
        mapper.insertOperatorLog(operatorLog);
    }
}
